home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / mega src / Source / chattr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-17  |  7.1 KB  |  310 lines  |  [TEXT/KAHL]

  1. /* ========== the commmand file: ==========
  2.  
  3.     chattr.c
  4.     
  5.     Copyright (c) 1993,1994 Newport Software Development
  6.     
  7.     You may distribute unmodified copies of this file for
  8.     noncommercial purposes.  You may use this file as a
  9.     reference when writing your own nShell(tm) commands.
  10.     
  11.     All other rights are reserved.
  12.     
  13.    ========== the commmand file: ========== */
  14.  
  15. #include <script.h>
  16. #include <string.h>
  17.  
  18. #include "nshc.h"
  19.  
  20. #include "arg_utl.proto.h"
  21. #include "fss_utl.proto.h"
  22. #include "nshc_utl.proto.h"
  23. #include "str_utl.proto.h"
  24.  
  25. // data definition - this struct is the root of all data
  26.  
  27. typedef struct {
  28.  
  29.     int        got_fss;        // 0 if FSSpec calls are not available
  30.     int        arg;            // position in arg list
  31.     
  32.     int        got_one;        // 0 until header is printed
  33.     
  34.     int        change_type;    // 0 if none, or arg pos of "-t"
  35.     OSType    new_type;
  36.     
  37.     int        change_creator;    // 0 if none, or arg pos of "-c"
  38.     OSType    new_creator;
  39.  
  40. } t_chattr_data;
  41.  
  42. typedef    t_chattr_data    **chattr_hndl;
  43.  
  44. /* ======================================== */
  45.  
  46. // prototypes - utility
  47.  
  48. int  chattr_get_OSType(t_nshc_parms *nshc_parms, int arg, OSType *selector);
  49. void chattr_bad( t_nshc_parms *nshc_parms, int code );
  50. void chattr_bad_file( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, StringPtr msg );
  51. void chattr_good( t_nshc_parms *nshc_parms );
  52.  
  53. // prototypes - file routines
  54.  
  55. void  chattr_one( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_chattr_data **hData );
  56.  
  57. // prototypes - state machine
  58.  
  59. void chattr_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls  );
  60. void chattr_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  61. void chattr_stop( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  62.  
  63. /* ======================================== */
  64.  
  65. // utility routines
  66.  
  67. int chattr_get_OSType(t_nshc_parms *nshc_parms, int arg, OSType *os_type)
  68. {
  69.     char    c;
  70.     char    *p;
  71.     int        i;
  72.     int        success;
  73.     
  74.     if (arg >= nshc_parms->argc)
  75.         return(0);
  76.     
  77.     success = 1;
  78.     *os_type = 0;
  79.     
  80.     p = &nshc_parms->arg_buf[ nshc_parms->argv[ arg ] ];
  81.     
  82.     for (i = 0 ; i < 4 ; i++ )
  83.         if ( c = *p++ ) {
  84.             *os_type = *os_type << 8;
  85.             *os_type = *os_type + c;
  86.             }
  87.         else
  88.             success = 0;
  89.             
  90.     if (*p) success = 0;
  91.     
  92.     return(success);
  93. }
  94.     
  95. /* ======================================== */
  96.  
  97. void chattr_bad(  t_nshc_parms *nshc_parms, int code )
  98. {
  99.     nshc_parms->action = nsh_stop;
  100.     nshc_parms->result = code;
  101. }
  102.     
  103. /* ======================================== */
  104.  
  105. void chattr_bad_file(  t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, StringPtr msg )
  106. {
  107.  
  108.     nshc_calls->NSH_putStr_err("\pchattr: File access error (");
  109.     nshc_calls->NSH_putStr_err(msg);
  110.     nshc_calls->NSH_putStr_err("\p)\r");
  111.  
  112.     nshc_parms->action = nsh_stop;
  113.     nshc_parms->result = NSHC_ERR_GENERAL;
  114. }
  115.     
  116. /* ======================================== */
  117.  
  118. void chattr_good(  t_nshc_parms *nshc_parms )
  119. {
  120.     nshc_parms->action = nsh_stop;
  121.     nshc_parms->result = 0;
  122. }
  123.  
  124. /* ======================================== */
  125.  
  126. // file access routines
  127.  
  128. /* ======================================== */
  129.  
  130. void chattr_one( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_chattr_data **hData )
  131. {
  132.     int        result;
  133.     FSSpec    fsspec;
  134.     FInfo    fndrInfo;
  135.     int        write;
  136.     
  137.     // =====> convert argument to fsspec
  138.     
  139.     result = arg_to_fss( nshc_parms, nshc_calls, (**hData).arg, &fsspec );
  140.  
  141.     (**hData).arg++;
  142.     
  143.     if (result) {
  144.         chattr_bad( nshc_parms, result );
  145.         return;
  146.         }
  147.     
  148.     result = fss_GetFInfo((**hData).got_fss, &fsspec, &fndrInfo);
  149.                 
  150.     if (result == fnfErr) {
  151.         nshc_calls->NSH_putStr_err("\pchattr: Not a file (");
  152.         nshc_calls->NSH_putStr_err((StringPtr)fsspec.name);
  153.         nshc_calls->NSH_putStr_err("\p)\r");
  154.         return;
  155.         }
  156.     
  157.     if (!result) {
  158.     
  159.         write = 0;
  160.     
  161.         if ( (**hData).change_type ) {
  162.             write = 1;
  163.             fndrInfo.fdType = (**hData).new_type;
  164.             }
  165.             
  166.         if ( (**hData).change_creator ) {
  167.             write = 1;
  168.             fndrInfo.fdCreator = (**hData).new_creator;
  169.             }
  170.             
  171.         if (write) {
  172.             result = fss_SetFInfo((**hData).got_fss, &fsspec, &fndrInfo);
  173.             if (!result)
  174.                 result = fss_wake_parent( &fsspec );
  175.             }
  176.             
  177.         if (!(**hData).got_one) {
  178.             nshc_calls->NSH_puts("  Crea   Type  Name\r");
  179.             nshc_calls->NSH_puts(" ------ ------ ----\r");
  180.             (**hData).got_one = 1;
  181.             }
  182.                 
  183.         nshc_calls->NSH_printf( " '%.4s' '%.4s' ", &fndrInfo.fdCreator, &fndrInfo.fdType );
  184.         nshc_calls->NSH_putStr( (StringPtr)fsspec.name );
  185.         nshc_calls->NSH_putchar( '\r' );
  186.         
  187.         }
  188.     
  189.     if ( result )
  190.         chattr_bad_file( nshc_parms, nshc_calls, (StringPtr)fsspec.name );
  191. }
  192.  
  193. /* ======================================== */
  194.  
  195. // state machine - core routines
  196.  
  197. /* ======================================== */
  198.  
  199. void chattr_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls  )
  200. {
  201.     int            arg;
  202.     OSType        os_type;
  203.     chattr_hndl    hData;    // handle to hold our data
  204.     
  205.     if (nshc_parms->argc < 2) {
  206.         nshc_calls->NSH_putStr_err( "\pUsage: chattr file [file...] [-t type] [-c crea]\r" );
  207.         chattr_bad( nshc_parms, NSHC_ERR_PARMS );
  208.         return;
  209.         }
  210.         
  211.     nshc_parms->action = nsh_continue;
  212.  
  213.     hData = (chattr_hndl)NewHandleClear(sizeof(t_chattr_data));
  214.     
  215.     if (hData) {
  216.     
  217.         (**hData).arg = 1;                    // start at the arg = 1 position
  218.         (**hData).got_fss = fss_test();        // test if we can use FSSpec calls
  219.         
  220.         // test if we are doing a type change
  221.         
  222.         if (arg = nshc_got_option( nshc_parms, 't' ))
  223.             if (chattr_get_OSType( nshc_parms, arg+1, &os_type)) {
  224.                 (**hData).change_type = arg;
  225.                 (**hData).new_type = os_type;
  226.                 }
  227.             else {
  228.                 nshc_calls->NSH_putStr_err( "\pchattr: Bad OSType given for type.\r" );
  229.                 chattr_bad( nshc_parms, NSHC_ERR_PARMS );
  230.                 }
  231.             
  232.         // test if we are doing a creator change
  233.         
  234.         if (arg = nshc_got_option( nshc_parms, 'c' ))
  235.             if (chattr_get_OSType( nshc_parms, arg+1, &os_type)) {
  236.                 (**hData).change_creator = arg;
  237.                 (**hData).new_creator = os_type;
  238.                 }
  239.             else {
  240.                 nshc_calls->NSH_putStr_err( "\pchattr: Bad OSType given for creator.\r" );
  241.                 chattr_bad( nshc_parms, NSHC_ERR_PARMS );
  242.                 }
  243.             
  244.         nshc_parms->data = (Handle)hData;
  245.         }
  246.     else {
  247.         nshc_calls->NSH_putStr_err( "\pchattr: Could not allocate storage.\r" );
  248.         chattr_bad( nshc_parms, NSHC_ERR_MEMORY );
  249.         }
  250. }
  251.  
  252. /* ======================================== */
  253.  
  254. void chattr_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  255. {
  256.     int        i;
  257.     int        arg;
  258.     chattr_hndl    hData;
  259.     
  260.     if (hData = (chattr_hndl)nshc_parms->data) {
  261.     
  262.         arg = (**hData).arg;
  263.         
  264.         while ( ( arg == (**hData).change_type ) || ( arg == (**hData).change_creator ) ) {
  265.             arg += 2;
  266.             (**hData).arg = arg;
  267.             }
  268.  
  269.         if (arg >= nshc_parms->argc)
  270.             chattr_good( nshc_parms );
  271.         else
  272.             chattr_one( nshc_parms, nshc_calls, hData );
  273.  
  274.         }
  275. }
  276.  
  277. /* ======================================== */
  278.  
  279. void chattr_stop( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  280. {
  281.     chattr_hndl    hData;
  282.     
  283.     if (hData = (chattr_hndl)nshc_parms->data)
  284.         DisposeHandle(nshc_parms->data);
  285.         
  286.     nshc_parms->action = nsh_idle;
  287. }
  288.  
  289. /* ======================================== */
  290.  
  291. void main(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  292. {
  293.     
  294.     if (nshc_bad_version( nshc_parms, nshc_calls, NSHC_VERSION )) return;
  295.     
  296.     switch (nshc_parms->action) {
  297.         case nsh_start:
  298.             chattr_start(nshc_parms, nshc_calls);
  299.             break;
  300.         case nsh_continue:
  301.             chattr_continue(nshc_parms, nshc_calls);
  302.             break;
  303.         case nsh_stop:
  304.             chattr_stop(nshc_parms, nshc_calls);
  305.             break;
  306.         }
  307. }
  308.  
  309. /* ======================================== */
  310.